Skip to content

feat(python-lsp)!: replace the old pylsp with zuban and ruff#1528

Merged
charliie-dev merged 12 commits intoayamir:mainfrom
Cloud0310:main
Nov 24, 2025
Merged

feat(python-lsp)!: replace the old pylsp with zuban and ruff#1528
charliie-dev merged 12 commits intoayamir:mainfrom
Cloud0310:main

Conversation

@Cloud0310
Copy link
Copy Markdown
Contributor

@Cloud0310 Cloud0310 commented Oct 9, 2025

Note

See previous PR #1489 and #1172 for previous details.
Due to pyrefly is still not reached beta yet, we choose to wait its first beta release, as it doesn't have any comlicated refactor capibility for now.
The PR now is converted into a draft now, the information about pyrefly could retrived here and facebook/pyrefly#344. And this would likely to be a BREAKING CHANGE once merged.

Summary

As we are searching for a better Python LSP, and there has been updates on pyrefly as a better choice for this, which is now mature and solid, I think its time to move on for pyrefly as the default python lsp.

Details

  1. deleted: previous dependencies for pylsp, remove extra config
  2. added: pyrefly (main python lsp) and ruff (format and lint) and keep the default behavior backward compatible.

@Cloud0310 Cloud0310 changed the title feat(lsp): replace the old pylsp with pyrefly and ruff feat(python-lsp): replace the old pylsp with pyrefly and ruff Oct 9, 2025
@charliie-dev
Copy link
Copy Markdown
Collaborator

does pyrefly's and ruff's default config gd enough?
otherwise we might need to add some language server config in lua/modules/configs/completion/servers.(check other language server's config as reference.

As mentioned in #1528, keep the ruff config align with previous config.

This includes:
1. set default line length to 88, as `black`'s default behavior
2. align with previous linter config

As for the pyrefly lsp config, I guess the default is good to go.
@Cloud0310
Copy link
Copy Markdown
Contributor Author

Cloud0310 commented Oct 9, 2025

does pyrefly's and ruff's default config gd enough? otherwise we might need to add some language server config in lua/modules/configs/completion/servers.(check other language server's config as reference.

Thanks for your kindly remind, I check up the previous config for pylsp, and pyrefly config docs, and ruff config doc.
I commited agian to fully remove the pylsp.lua config, and align the behavior of ruff with previous config.
If there's something we can config further for user experience, please let me know.

@Cloud0310
Copy link
Copy Markdown
Contributor Author

Another thing is that, I suggest we should ask other maintainers for their opinion on this PR about whether its time to switch and what can we improve about lsp/linter/formatter config.

Comment thread lua/modules/configs/completion/servers/pylsp.lua
Comment thread lua/modules/configs/completion/servers/ruff.lua Outdated
@Cloud0310 Cloud0310 changed the title feat(python-lsp): replace the old pylsp with pyrefly and ruff feat(python-lsp)!: replace the old pylsp with pyrefly and ruff Oct 9, 2025
@Cloud0310 Cloud0310 marked this pull request as draft October 10, 2025 10:53
@ayamir
Copy link
Copy Markdown
Owner

ayamir commented Oct 11, 2025

Maybe I can't review it now.

  1. Recently I'm busy on working for my job and have no enough spare time to review it. ByteDance you know, byte and heart, only one can dance.
  2. It’s been ages since I touched python, my use case is not confident.

@Cloud0310
Copy link
Copy Markdown
Contributor Author

Now there's another option for Python LSP, Zuban claims to support more lsp features, and look promising. We should take one that into consideration as well.

@charliie-dev
Copy link
Copy Markdown
Collaborator

Announcing Pyrefly Beta

@Cloud0310
Copy link
Copy Markdown
Contributor Author

Cloud0310 commented Nov 20, 2025

Announcing Pyrefly Beta

I saw it as well, but it's kinda late (UTC+8 1a.m.) now, tomorrow I will try to test it.

@Cloud0310
Copy link
Copy Markdown
Contributor Author

Cloud0310 commented Nov 21, 2025

I guess for my use case for scripting in python with types, the mentioned refactor feature is working properly and all other things are working as intended. So I guess its ready for review and test.

Another thing is the new zuban lsp, should we consider it instead of pyrefly?
There's a feature comparison table here by zuban (kinda old for current pyrefly version 0.4x), and it claims to be faster then pyrefly and having better compatibility.

ref: @misumisumi @charliie-dev

@Cloud0310 Cloud0310 marked this pull request as ready for review November 21, 2025 07:06
@charliie-dev
Copy link
Copy Markdown
Collaborator

As zuban's readme stated:

Zuban is 20–200× faster than Mypy, while using roughly half the memory and CPU compared to Ty and Pyrefly.

Mason support:
image

image

yeah, sure. why not lol

@Cloud0310
Copy link
Copy Markdown
Contributor Author

Found this amazing test set from python/typing, I will try to re-test, and then I guess we can choose a base on this test.

@Cloud0310
Copy link
Copy Markdown
Contributor Author

results.html
I guess as the test demonstrates, zuban is better?

@charliie-dev
Copy link
Copy Markdown
Collaborator

results.html I guess as the test demonstrates, zuban is better?

can we add ty to the list?

@Cloud0310
Copy link
Copy Markdown
Contributor Author

results.html I guess as the test demonstrates, zuban is better?

can we add ty to the list?

Guess nothing is working on that one. Even basic array type infer.

@charliie-dev
Copy link
Copy Markdown
Collaborator

then +1 for zuban, lets gooo

@misumisumi
Copy link
Copy Markdown
Collaborator

misumisumi commented Nov 21, 2025

I also think it would be better to choose zuban now.

P.S.
There are some concerns, such as zuban being a personal project of the creator of jedi, so there are concerns about sustainability, and pyrefly getting more attention (from repo star).
But if pyrefly become better tool, we just switch to it.

@Cloud0310
Copy link
Copy Markdown
Contributor Author

I also think it would be better to choose zuban now.

P.S. There are some concerns, such as zuban being a personal project of the creator of jedi, so there are concerns about sustainability, and pyrefly getting more attention (from repo star). But if pyrefly become better tool, we just switch to it.

As for the personal project problem, the current solution python-lsp is based on jedi as well, so I guess the community solution is absolutely fine.

Personally, I would like the solution of using zuban for now. In the long term, if there's better solution with python lsp, I guess it wouldn't be a problem to switch to it.

P.S. I happen to know one of the contributors of zuban and pyrefly, @asukaminato0721. The situation about all mentioned lsp inplementations is as this blog (Simplified Chinese) suggests.

As [PR 1528] discussion suggests, zuban is more implemented and has less
memory footprint.
@Cloud0310
Copy link
Copy Markdown
Contributor Author

So maybe we could merge this? @charliie-dev @misumisumi

@charliie-dev charliie-dev changed the title feat(python-lsp)!: replace the old pylsp with pyrefly and ruff feat(python-lsp)!: replace the old pylsp with zuban and ruff Nov 22, 2025
…_list`

Signed-off-by: Charles Chiu <mail@charliie.dev>
Copy link
Copy Markdown
Collaborator

@charliie-dev charliie-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just tested on my private python repo, seems right lol
LGTM

@asukaminato0721
Copy link
Copy Markdown

asukaminato0721 commented Nov 22, 2025

imo, both are excellent choices.

Zuban did very well in the standard.

Pyrefly just released a beta version and will be the CI tool for PyTorch.

d = {"2": 2}
if d.get("1") is None:
    raise
x = d.get("1")

Now only Pyrefly can infer that x is int. facebook/pyrefly@70b058e

Copy link
Copy Markdown
Collaborator

@misumisumi misumisumi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread lua/modules/configs/completion/servers/pylsp.lua
Copy link
Copy Markdown
Owner

@ayamir ayamir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 💯

@charliie-dev charliie-dev merged commit cebd96e into ayamir:main Nov 24, 2025
2 checks passed
charliie-dev added a commit that referenced this pull request Apr 1, 2026
* feat: use vim.env and vim.uv for env and cwd access (#1507)

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

* fix: LSP start logic (#1504)

* Revert "fix: remove manual `LspStart`, close #1478. (#1479)"

This reverts commit 7dab4b9.

* Revert "fixup(#1466): load lsp config with proper event. (#1472)"

This reverts commit 53eeeec.

* fix: LSP start logic

This should acc fix #1472 and #1479 cuz iirc the root cause was that lspconfig
changed how `LspStart` works. Now it only starts one _specific_ server (passed
via the first argument), instead of starting all matching servers automatically.
So we gotta manually start all the servers that match the current filetype
instead.

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

* fix: redundant return

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

* fix: invoke `:LspStart` correctly

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

---------

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>
Co-authored-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

* feat(mason)!: migrate to v2.x (#1502)

* feat(mason)!: migrate to v2.x

Just wrapped up going thru all the changes in mason 2.x (and nvim 0.11 too)!
This should be a follow up to #1466 and (hopefully) fix all the issues related
to the updated LSP API (like servers not spawning and other weirdness) and works
together w #1496.

Acc the main issue was that some mason package names don't match their names in
lspconfig, so just using `lsp_deps` directly works for most, but breaks a bunch
of others (tldr: that mismatch is what was causing all the edge cases and broken
behavior).

I also went ahead and enabled `automatic_installation` because why not lol means
we don't have to manually call `vim.lsp.enable()` for everything, which might
save a tiny bit of perf too.

Didn't test this super thoroughly yet so pls lmk if anything's still broken!

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

* fixup! feat(mason)!: migrate to v2.x

* fixup! feat(mason)!: migrate to v2.x

* fixup! feat(mason)!: migrate to v2.x

* fix: LSP start logic (#1496)

* Revert "fix: remove manual `LspStart`, close #1478. (#1479)"

This reverts commit 7dab4b9.

* Revert "fixup(#1466): load lsp config with proper event. (#1472)"

This reverts commit 53eeeec.

* fix: LSP start logic

This should acc fix #1472 and #1479 cuz iirc the root cause was that lspconfig
changed how `LspStart` works. Now it only starts one _specific_ server (passed
via the first argument), instead of starting all matching servers automatically.
So we gotta manually start all the servers that match the current filetype
instead.

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

---------

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

* fix: unresolved nvim_lsp

* feat(lsp): unify language server setup

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

---------

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>
Co-authored-by: ayamir <lgt986452565@gmail.com>

* chore(lockfile): auto update lazy-lock.json

* refactor(tool): simplify fzf-lua usage and improve lazy loading (#1506)

* refactor(tool): simplify fzf-lua usage and improve lazy loading

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

* feat: minor optimizations

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>

* style: remove reduntant short circuit logic.

---------

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>
Co-authored-by: ayamir <lgt986452565@gmail.com>

* fix: avoid require nil.

* chore(lockfile): auto update lazy-lock.json

* fix(event): fix "Autojump to last edit" event (#1509)

* chore(lockfile): auto update lazy-lock.json

* chore(gh_act): update components (#1510)

* chore(lockfile): auto update lazy-lock.json

* fix: abnormal window behavior when use fzf (#1511)

* chore(lockfile): auto update lazy-lock.json

* fix(project_nvim): rename module name to project (#1514)

* chore(lockfile): auto update lazy-lock.json

* fix: adapt codecompanion newest api

* chore(lockfile): auto update lazy-lock.json

* fix: use realpath of vim related path (#1516)

* chore(lockfile): auto update flake.lock

* fix: only use realpath for vim_path (#1522)

* chore(lockfile): auto update lazy-lock.json

* fix: typos in comment and install message (#1525)

* chore(lockfile): auto update lazy-lock.json

* chore(lockfile): auto update flake.lock

* fix: temporarily disable project.nvim 'lsp' attach mode (#1529)

See
[DrKJeff16/project.nvim#24](DrKJeff16/project.nvim#24)
for details

* chore(lockfile): auto update lazy-lock.json

* fix(lspconfig): remove deprecated legacy framework of lspconfig (#1530)

Co-authored-by: misumisumi <s.kobayashi@misumi-sumi.com>

* fix(#1520): disable swapfile (#1531)

* chore(lockfile): auto update lazy-lock.json

* perf(ci): update ci config (#1534)

* perf(ci): make bot commit verified and add `dependabot` for ci component autoupdate

* chore(doc): update username from `CharlesChiuGit` to `charliie-dev`

* chore(lockfile): auto update lazy-lock.json

* fix(lockfile): update flake.lock to make ci works (#1535)

* chore(ci): set schedule to every 2 week (#1536)

* chore(lockfile): auto update lazy-lock.json

* chore(lockfile): auto update flake.lock

* fix(project): re-enable LSP detection (#1539)

Signed-off-by: Guennadi Maximov C <g.maxc.fox@protonmail.com>

* chore(lockfile): auto update lazy-lock.json

* feat(python-lsp)!: replace the old pylsp with zuban and ruff (#1528)

* chore(lockfile): auto update lazy-lock.json

* chore(ci.deps): bump actions/checkout in the actions-dependencies group (#1542)

Bumps the actions-dependencies group with 1 update: [actions/checkout](https://github.com/actions/checkout).


Updates `actions/checkout` from 5 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(lockfile): auto update lazy-lock.json

* chore: pin codecompanion in case breaking change temprarily (#1543)

details: olimorris/codecompanion.nvim#2439

Co-authored-by: liuguangtian.1024 <liuguangtian.1024@bytedance.com>

* chore(lockfile): auto update flake.lock

* chore(lockfile): auto update lazy-lock.json

* [migration] set nvim-treesitter to main branch, close #1541 (#1544)

* feat!(plugins.editor): set `nvim-treesitter` and `nvim-treesitter-textobjects` branch to `main`

* fix(lockfile): manually remove lockfile to make branch-changing effective

* feat!(configs.editor): migrate `treesitter` and `ts-textobjects` config

* feat!(keymap.editor): move `ts-textobjects`' keymap here

---------

Signed-off-by: Charles Chiu <mail@charliie.dev>

* chore(lockfile): auto update lazy-lock.json

* fix(edgy): add nil check for toggleterm terminal (#1546)

Fixes #1545

When toggleterm terminal has not been created yet, `require("toggleterm.terminal").get(1)` returns nil, causing an error when trying to access `term.direction`.

This commit adds a nil check before accessing the direction property to prevent the error.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore(lockfile): auto update lazy-lock.json

* fix(treesitter): add autocmd for highlight and fix load plugin (#1547)

Co-authored-by: misumisumi <s.kobayashi@misumi-sumi.com>

* chore(lockfile): auto update lazy-lock.json

* chore(lockfile): auto update flake.lock

* chore(lockfile): auto update flake.lock

* fix: using project's clang-format config first. (#1550)

* fix: using project's clang-format config first.

* fix: style lua ci/cd

* chore(lockfile): auto update lazy-lock.json

* chore(lockfile): auto update flake.lock

* fix(ruff): use project config first (#1558)

* Fix deprecated tree-sitter package and update codecompanion v18 (#1557)

* fix(codecompanion): update to v18

* fix(settings): remove jsonc treesitter

- jsonc is not available on upstream by nvim-treesitter/nvim-treesitter#8316

---------

Co-authored-by: misumisumi <s.kobayashi@misumi-sumi.com>

* chore(lockfile): auto update lazy-lock.json

* chore(tool.project): update `project.nvim` config (#1559)

* chore(lockfile): auto update lazy-lock.json

* chore(lockfile): auto update flake.lock

* chore(lockfile): auto update flake.lock

* chore(lockfile): auto update flake.lock

* feat(keymap): add `<leader>dC` to close dapui.

#1552

* chore(lockfile): auto update lazy-lock.json

* chore(lockfile): auto update flake.lock

* refactor: use telescope/fzf-lua to replace glance.nvim (#1519)

* refactor: use telescope/fzf-lua to replace glance.nvim

* fix(ci): lint code

* refactor(ci): remove lint args

* chore(lockfile): auto update lazy-lock.json

* chore(lockfile): auto update flake.lock

---------

Signed-off-by: Jint-lzxy <50296129+Jint-lzxy@users.noreply.github.com>
Signed-off-by: Guennadi Maximov C <g.maxc.fox@protonmail.com>
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Charles Chiu <mail@charliie.dev>
Co-authored-by: jint_lzxy_ <50296129+Jint-lzxy@users.noreply.github.com>
Co-authored-by: ayamir <lgt986452565@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: wenqian <lazycat7706@gmail.com>
Co-authored-by: Cloud <60375730+Cloud0310@users.noreply.github.com>
Co-authored-by: MiSumiSumi <dragon511southern@gmail.com>
Co-authored-by: misumisumi <s.kobayashi@misumi-sumi.com>
Co-authored-by: Guennadi Maximov C <g.maxc.fox@protonmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: liuguangtian.1024 <liuguangtian.1024@bytedance.com>
Co-authored-by: Zonghao Yuan <64521992+zonghaoyuan@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: ayamir <61657399+ayamir@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants